﻿//==========================================================
//Đã sửa bởi tranninh_86_yb@yahoo.com ngày 24/06/2013
//==========================================================

using System;
using System.Data;
using System.Data.SqlClient;

namespace prjKQXS_DLL
{
    public class clsThietLapLai
    {
        //Cài đặt event OnError để bắt các lỗi chưa được xử lý
        public delegate void OnErrorHandler(Exception e);
        public event OnErrorHandler OnError;

        //Cài đặt event OnAction để thông báo các trạng thái kết quả
        public delegate void OnActionHandler(SqlException e);
        public event OnActionHandler OnAction;

        #region Methods ================================================================
        public void autoTLLX(int cap)
        {
            //KIỂM TRA VÀ THIẾT LẬP LÃI XUẤT TỰ ĐỘNG CHO CÁC ĐẠI LÝ CẤP x (chưa kết thúc tính lãi <=> isKT=0)
            //================================================================================================

            try
            {
                //Bước 1: Lấy ra mã các đại lý cấp x đã gửi ít nhất 1 kỳ và chưa kết thúc tính lãi
                SqlConnection conn = new SqlConnection(BienTc.connString);
                conn.Open();
                SqlDataAdapter da = new SqlDataAdapter("proc_autoTLLX_getList", conn);
                da.SelectCommand.CommandType = CommandType.StoredProcedure;
                da.SelectCommand.Parameters.AddWithValue("@cap", cap);
                DataTable dtList = new DataTable();
                da.Fill(dtList);

                //Bước 2: Kiểm tra xem đã thiết lập lãi xuất đầy đủ cho mã thứ i hay chưa
                //  - Nếu đầy đủ rồi thì chuyển qua trường hợp tiếp theo
                //  - Nếu chưa đầy đủ thì bổ sung vào các kỳ còn thiếu
                if (dtList.Rows.Count > 0)
                {
                    for (int i = 0; i < dtList.Rows.Count; i++)
                    {
                        int id;
                        if (cap == 1) id = (int)dtList.Rows[i]["DMCanBoID"];
                        else id = (int)dtList.Rows[i]["HopDongID"];

                        if (!TLLXisOK(cap, id))
                        {
                            #region Bổ sung kỳ còn thiếu ----------------------------------
                            string sql = "";
                            if (cap == 1) sql = "INSERT TLLX1 (DMCanBoID, Ky, LoaiKyHan, Lai_Xuat) VALUES (@ID, @Ky, @LoaiKyHan, @Lai_Xuat)";
                            else sql = "INSERT TLLX2 (HopDongID, Ky, LoaiKyHan, Lai_Xuat) VALUES (@ID, @Ky, @LoaiKyHan, @Lai_Xuat)";
                            SqlCommand cmd = new SqlCommand(sql, conn);
                            cmd.Parameters.Clear();

                            string s = "";
                            if (cap == 1) s = "SELECT LoaiKyHan, Lai_xuat FROM TLLX1 WHERE DMCanBoID=" + id + " ORDER BY Ky";
                            else s = "SELECT LoaiKyHan, Lai_xuat FROM TLLX2 WHERE HopDongID=" + id + " ORDER BY Ky";
                            da = new SqlDataAdapter(s, conn);
                            DataTable dt = new DataTable();
                            da.Fill(dt);

                            int LoaiKyHan = Convert.ToInt32(dt.Rows[dt.Rows.Count - 1]["LoaiKyHan"]);
                            cmd.Parameters.AddWithValue("@LoaiKyHan", LoaiKyHan);

                            Decimal laixuat = Convert.ToDecimal(dt.Rows[dt.Rows.Count - 1]["Lai_xuat"]);
                            cmd.Parameters.AddWithValue("@Lai_Xuat", laixuat);

                            cmd.Parameters.AddWithValue("@ID", id);
                            cmd.Parameters.AddWithValue("@Ky", dt.Rows.Count + 1);
                            int result = cmd.ExecuteNonQuery();
                            #endregion ----------------------------------------------------
                        }
                    }
                }
            }
            catch (SqlException e)
            {
                OnAction(e);
            }
            catch (Exception e)
            {
                OnError(e);
            }
        }

        public void Insert(int cap, int id, DateTime TuNgay, int LoaiKyHan, decimal LX)
        {
            try
            {
                SqlConnection conn = new SqlConnection(BienTc.connString);
                conn.Open();
                string sql;
                DataTable dt;

                if (cap == 1)
                {
                    dt = clsCommon.FillData("SELECT DMCanBoID FROM TLLX1 WHERE DMCanBoID=" + id);
                    sql = "INSERT TLLX1 (DMCanBoID, Ky, LoaiKyHan, Lai_xuat) VALUES (@ID, @Ky, @LoaiKyHan, @LaiXuat)";
                }
                else
                {
                    dt = clsCommon.FillData("SELECT HopDongID FROM TLLX2 WHERE HopDongID=" + id);
                    sql = "INSERT TLLX2 (HopDongID, Ky, LoaiKyHan, Lai_xuat) VALUES (@ID, @Ky, @LoaiKyHan, @LaiXuat)";
                }

                SqlCommand cmd = new SqlCommand(sql, conn);
                cmd.Parameters.AddWithValue("@ID", id);
                cmd.Parameters.AddWithValue("@Ky", dt.Rows.Count + 1);
                cmd.Parameters.AddWithValue("@LoaiKyHan", LoaiKyHan);
                cmd.Parameters.AddWithValue("@LaiXuat", LX);
                int result = cmd.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                OnAction(e);
            }
            catch (Exception e)
            {
                OnError(e);
            }
        }

        public int Update(int cap, int id, DateTime TuNgay, int LoaiKyHan, decimal LX)
        {
            int result = 0;

            try
            {
                SqlConnection conn = new SqlConnection(BienTc.connString);
                conn.Open();

                if (cap == 1)
                {
                    string sql = "UPDATE vTLLX1 SET LoaiKyHan=@LoaiKyHan, Lai_xuat=@Lai_Xuat " +
                        "WHERE (day(Tu_Ngay)= " + TuNgay.Day + " and month(Tu_Ngay)= " + TuNgay.Month +
                        " and year(Tu_Ngay)= " + TuNgay.Year + ") and DMCanBoID= @DMCanBoID";
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.Parameters.AddWithValue("@LoaiKyHan", LoaiKyHan);
                    cmd.Parameters.AddWithValue("@Lai_Xuat", LX);
                    cmd.Parameters.AddWithValue("@DMCanBoID", id);
                    result = cmd.ExecuteNonQuery();
                }
                else
                {
                    string sql = "UPDATE vTLLX2 SET LoaiKyHan=@LoaiKyHan, Lai_xuat=@Lai_Xuat " +
                        "WHERE (day(Tu_Ngay)= " + TuNgay.Day + " and month(Tu_Ngay)= " + TuNgay.Month +
                        " and year(Tu_Ngay)= " + TuNgay.Year + ") and HopDongID= @HopDongID";
                    SqlCommand cmd = new SqlCommand(sql, conn);
                    cmd.Parameters.AddWithValue("@LoaiKyHan", LoaiKyHan);
                    cmd.Parameters.AddWithValue("@Lai_Xuat", LX);
                    cmd.Parameters.AddWithValue("@HopDongID", id);
                    result = cmd.ExecuteNonQuery();
                }
            }
            catch (SqlException e)
            {
                OnAction(e);
            }
            catch (Exception e)
            {
                OnError(e);
            }

            return result;
        }
        #endregion Methods =============================================================


        #region Functions ==============================================================
        /// <summary>
        /// Hàm này kiểm tra xem đại lý đã thiết lập lãi xuất đầy đủ chưa
        /// </summary>
        /// <param name="cap">Cấp đại lý</param>
        /// <param name="id">LaiXuat_CB.DMCanBoID (đối với đại lý cấp I) hoặc LaiXuat_DL.HopDongID (đối với đại lý cấp II)</param>
        /// <returns></returns>
        private bool TLLXisOK(int cap, int id)
        {
            bool ok = true;
            //Đặc điểm nhận biết: khi đại lý thiết lập lãi xuất đầy đủ thì NgayTLKyTiep luôn > ngày hiện tại, do đó:
            //- Nếu chưa kết thúc tính lãi mà NgayTLKyTiep <= ngày hiện tại (tức là chưa thiết lập lãi xuất đầy đủ) => ok=false

            try
            {
                SqlConnection conn = new SqlConnection(BienTc.connString);
                conn.Open();

                string sql = "";
                if (cap == 1) sql = "SELECT isKT FROM LAIXUAT_CB WHERE DMCanBoID = " + id;
                else sql = "SELECT isKT FROM LAIXUAT_DL WHERE HopDongID = " + id;

                SqlCommand cmd = new SqlCommand(sql, conn);
                bool isKT = (bool)cmd.ExecuteScalar();   //iKT=false: chưa kết thúc tính lãi; iKT=true: đã kết thúc tính lãi

                DateTime NgayTLKyTiep = clsCommon.generateNgayTLKyTiep(cap, id);
                if (isKT == false && NgayTLKyTiep.Date <= DateTime.Now.Date) ok = false;
            }
            catch (SqlException e)
            {
                OnAction(e);
            }
            catch (Exception e)
            {
                OnError(e);
            }

            return ok;
        }

        private DataTable SetTienGocDauKy(int cap, int id)
        {
            DataTable dt = new DataTable();

            try
            {
                //Cap 1: T.DMCanBoID, CB.Tien_Goc AS Tien, Ky, Lai_xuat, LoaiKyHan, Tu_ngay, Den_Ngay (sắp xếp tăng dần theo Ky)
                //Cap 2: T.HopDongID, HD.So_Tien AS Tien, Ky, Lai_xuat, LoaiKyHan, Tu_ngay, Den_Ngay (sắp xếp tăng dần theo Ky)
                dt = clsCommon.loadDataSource_TLLX(cap, id);

                //Hàm này lấy ra giá trị ngày thanh lý hoặc ngày rút thế chấp trong csdl, nếu không có thì trả về new DateTime()
                DateTime NgayTLy = clsCommon.getNgayThanhLy(cap, id);
                DateTime NgayRutTC = clsCommon.getNgayRutTC(cap, id);

                if (dt.Rows.Count > 0)
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        //Hàm này thêm các cột TienGocDauKy, Tien_lai, TienGocMoi vào dt và điền giá trị cho chúng
                        clsCommon.XyLyNguon(cap, id, NgayTLy, NgayRutTC, ref dt, i, 1);
                    }
                }
            }
            catch (SqlException e)
            {
                OnAction(e);
            }
            catch (Exception e)
            {
                OnError(e);
            }

            return dt;
        }

        public DataTable loadData(int cap, int mode, DateTime TuNgay) //Thủ tục này để lấy nguồn cho gvDonVi
        {
            DataTable dt = new DataTable();

            try
            {
                SqlConnection conn = new SqlConnection(BienTc.connString);
                if (conn.State == ConnectionState.Closed) conn.Open();

                //Với rgMode.SelectedIndex == 1 Thủ tục lưu trữ sẽ lấy ra những record đã gửi và có ngày gửi (ngày bắt đầu kỳ gửi) = deTuNgay.DateTime
                //Với rgMode.SelectedIndex == 0:
                //- ĐLC1 thì:
                //Thủ tục lưu trữ sẽ lấy ra:
                // - Những record gửi lần đầu tiên. Đặc điểm xác định record gửi lần đầu tiên:
                //      + Có NGÀY BẮT ĐẦU (suy ra từ LAIXUAT_CB.NgayNopTC) = deTuNgay.DateTime;
                //      + Mã LAIXUAT_CB.DMCanBoID tương ứng không nằm trong tập hợp: mã các record có TLLX1.Ky=1 và TLLX1.Tu_Ngay=deTuNgay.DateTime)
                // - Những record đã gửi ít nhất 1 kỳ và có ngày tính lãi tiếp theo của kỳ gửi cuối cùng = deTuNgay.DateTime
                //- ĐLC2 thì:
                //Thủ tục lưu trữ sẽ lấy ra:
                // - Những record gửi lần đầu tiên. Đặc điểm xác định record gửi lần đầu tiên:
                //      + Có NGÀY BẮT ĐẦU (suy ra từ LAIXUAT_DL.NgayNopTC) = deTuNgay.DateTime.Date;
                //      + HOPDONG.ID tương ứng chưa xuất hiện trong bảng TLLX2
                // - Những record đã gửi ít nhất 1 kỳ và có ngày tính lãi tiếp theo của kỳ gửi cuối cùng = deTuNgay.DateTime.Date

                //Cap 1: LX.DMCanBoID, CB.Ma_DT AS MaCB, CB.Ten_DT AS TenCB, DV.Ten_DT AS TenDV, CB.Tien_Goc AS TienGocBD, MAX(Den_ngay) AS NgayTLKyTiep
                //Cap 2: LX.HopDongID, HD.Ma_DaiLy AS MaDL, HD.Ten_DaiLy AS TenDL, DV.Ten_DT AS TenDV, HD.So_Tien AS TienGocBD, MAX(Den_ngay) AS NgayTLKyTiep
                string sql = "proc_loadData_TLLX";
                SqlDataAdapter da = new SqlDataAdapter(sql, conn);
                da.SelectCommand.CommandType = CommandType.StoredProcedure;
                da.SelectCommand.Parameters.AddWithValue("@Cap", cap);
                da.SelectCommand.Parameters.AddWithValue("@mode", mode);
                da.SelectCommand.Parameters.AddWithValue("@NgayTLKyTiep", TuNgay.Date);
                da.Fill(dt);
                dt.Columns.Add("TienGocDauKy", Type.GetType("System.Decimal"));
                if (mode == 0) dt.Columns.Add("LaiXuat", Type.GetType("System.Decimal"));

                int id;
                DataTable dtTemp;

                //Cài đặt giá trị cho cột TienGocDauKy
                if (dt.Rows.Count > 0)
                {
                    decimal tiengocdauky = 0;
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        if (cap == 1) id = (int)dt.Rows[i]["DMCanBoID"];
                        else id = (int)dt.Rows[i]["HopDongID"];
                        dtTemp = SetTienGocDauKy(cap, id);
                        if (dtTemp.Rows.Count > 0)  //Nếu dtTemp có nhiều dòng thì dòng cuối cùng chứa tiengocdauky cần lấy, 
                        {
                            if (mode == 0)  //Nếu đang ở chế độ thiết lập lãi xuất cho kỳ hạn mới
                            {
                                tiengocdauky = (decimal)dtTemp.Rows[dtTemp.Rows.Count - 1]["TienGocMoi"];
                            }
                            else    //rgMode.SelectedIndex == 1 <=> Nếu đang ở chế độ sửa lãi xuất cho kỳ hạn đã có
                            {
                                for (int j = 0; j < dtTemp.Rows.Count; j++)
                                {
                                    if (((DateTime)dtTemp.Rows[j]["Tu_Ngay"]).Date == TuNgay.Date)
                                        tiengocdauky = (decimal)dtTemp.Rows[j]["TienGocDauKy"];
                                }
                            }
                        }
                        else tiengocdauky = (decimal)dt.Rows[i]["TienGocBD"];//nếu không thì tiengocdauky là tiền gốc nộp vào
                        dt.Rows[i]["TienGocDauKy"] = tiengocdauky;
                    }
                }
            }
            catch (SqlException e)
            {
                OnAction(e);
            }
            catch (Exception e)
            {
                OnError(e);
            }

            return dt;
        }
        #endregion Functions ===========================================================
    }
}
